<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xeokit Example</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
    <h1>Picking Surfaces with Full Precision</h1>
    <h2>Hover over objects to ray-pick them using the 'pickSurfacePrecision' option</h2>
    <h3>Components Used</h3>
    <ul>
        <li>
            <a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
               target="_other">Viewer</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
               target="_other">XKTLoaderPlugin</a>
        </li>
    </ul>
</div>
</body>
<script type="module">

    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import {
        Viewer,
        XKTLoaderPlugin,
        Node,
        Mesh,
        VBOGeometry,
        buildSphereGeometry,
        PhongMaterial,
        math, FastNavPlugin
    } from "../../dist/xeokit-sdk.min.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer and arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
        canvasId: "myCanvas",
        pickSurfacePrecisionEnabled: true // <<--- Enables the pickSurfacePrecision option for viewer.scene.pick()
    });

    viewer.scene.camera.eye = [10.45, 17.38, -98.31];
    viewer.scene.camera.look = [43.09, 0.5, -26.76];
    viewer.scene.camera.up = [0.06, 0.96, 0.16];

    //------------------------------------------------------------------------------------------------------------------
    // Load a model
    //------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const sceneModel = xktLoader.load({
        id: "myModel",
        src: "../../assets/models/xkt/v8/OTCConferenceCenter.xkt",
        edges: false
    });
    //------------------------------------------------------------------------------------------------------------------
    // Display an indicator wherever the pointer picks a surface
    //------------------------------------------------------------------------------------------------------------------

    var hitHelper = new (function () {

        const zeroVec = new Float64Array([0, 0, -1]);
        const quat = new Float64Array(4);

        var node = new Node(viewer.scene, {
            pickable: false,
            visible: true,
            position: [0, 0, 0],

            children: [
                new Mesh(viewer.scene, {
                    geometry: new VBOGeometry(viewer.scene, buildSphereGeometry({radius: .2})),
                    material: new PhongMaterial(viewer.scene, {emissive: [1, 0, 0], diffuse: [0, 0, 0]}),
                    pickable: false
                }),
                new Mesh(viewer.scene, {
                    geometry: new VBOGeometry(viewer.scene, {
                        primitive: "lines",
                        positions: [
                            0.0, 0.0, 0.0, 0.0, 0.0, -2.0
                        ],
                        indices: [0, 1]
                    }),
                    material: new PhongMaterial(viewer.scene, {emissive: [1, 1, 0], diffuse: [0, 0, 0], lineWidth: 4}),
                    pickable: false
                })
            ]
        });

        this.show = function (hit) {
            node.position = hit.worldPos;
            node.visible = true;

            (this._dir = this._dir || math.vec3()).set(hit.worldNormal || [0, 0, 1]);
            math.vec3PairToQuaternion(zeroVec, this._dir, quat);
            node.quaternion = quat;
        };

        this.hide = function () {
            node.visible = false;
        };
    })();

    //------------------------------------------------------------------------------------------------------------------
    // Dynamically pick surfaces of model with the pointer, show pick intersection with red sphere
    //------------------------------------------------------------------------------------------------------------------

    var lastEntity = null;
    var lastColorize = null;

    viewer.scene.input.on("mousemove", function (coords) {

        var hit = viewer.scene.pick({
            canvasPos: coords,
            pickSurface: true,  // <<------ This causes picking to find the intersection point on the entity
            pickSurfacePrecision: true // <<------ Do precise picking (can be slow - actually not the best for hovering)
        });

        if (hit) {

            if (!lastEntity || hit.entity.id !== lastEntity.id) {

                if (lastEntity) {
                    lastEntity.colorize = lastColorize;
                }

                lastEntity = hit.entity;
                lastColorize = hit.entity.colorize.slice();

                hit.entity.colorize = [0.0, 1.0, 0.0, 1.0];
            }

            hitHelper.show(hit);

        } else {

            if (lastEntity) {
                lastEntity.colorize = lastColorize;
                lastEntity = null;

                hitHelper.hide();
            }
        }
    });
</script>
</html>